from django.shortcuts import render
from django.views import View
from django.http import HttpResponse,JsonResponse
from django.http import QueryDict

# 安装图片验证码所需要的pillow模块
# pip install pillow
from utils.captcha.captcha import captcha   # 导入验证码生成模块中的captcha对象

from django_redis import get_redis_connection   # 缓存数据库
from . import constants # 导入已设置的过期时间全局变量

import logging  # 日志
# 导入日志器
logger = logging.getLogger('django')

from users.models import Users
from utils.json_fun import to_json_data
from utils.res_code import Code
import json
from .forms import CheckImgCodeForm


# Create your views here.
class ImageCode(View):
    """
    define image verification view
    /image_code/<uuid:image_code_id>/   # 接口的URL路径定义
    """
    #  1.创建一个类视图
    # 2.从前端获取参数UUID并校验
    # 3.生成验证码文本和验证码图片
    # 4.建立redis连接并且将图片验证码保存到redis
    # 5.验证码图片返回前端
    def get(self, request, image_code_id):  # 2.从前端获取参数UUID并校验
        # 3.生成验证码文本和验证码图片(其中文本保存到redis数据库，图片传给前端展示)
        text, image = captcha.generate_captcha()

        # 4.建立redis连接并且将图片验证码保存到redis
        con_redis = get_redis_connection(alias='verify_code')   # alias指定连接的数据库不写会去找默认库（default配置那个库）
        img_key = "img_{}".format(image_code_id)    # 构造存放数据的key（text作为保存value）
        # con_redis.setex(img_key, text)  # setex源码可见，可传入时间参数，为了不写死，设置全局变量，在当前app下设置constants.py文件
        con_redis.setex(img_key, constants.IMAGE_CODE_REDIS_EXPIRES, text)

        # 此处为新增
        logger.info("Image code:{}".format(text))

        # 5.验证码图片返回前端
        return HttpResponse(content=image, content_type='images/jpg')


class CheckUsernameView(View):
    """
    注册功能验证实现流程
    1.创建一个类视图
    2.校验参数
    3.查询数据
    4.返回校验的结果
    check whether the user exists
    # 1.创建一个类视图
    """
    # 2.校验参数
    def get(self,request, username):
        # 3.查询数据
        count = Users.objects.filter(username=username).count()

        # 4.返回校验的结果
        data = {
            'username': username,
            'count': count,
        }
        # return JsonResponse(data=data)
        return to_json_data(data=data)


class CheckMobileView(View):
    """
    校验手机号是否存在
    url:/moblie/(?P<moblie>1[3-9]\d{9})/
    功能验证实现流程
    1.创建一个类视图
    2.校验参数
    3.查询数据
    4.返回校验的结果
    """
    def get(self, request, mobile):
        data = {
            'mobile': mobile,
            'count': Users.objects.filter(mobile=mobile).count(),
        }
        return to_json_data(data=data)


class SmsCodeView(View):
    """
    发送短信验证码
    send mobile sms code
    POST  /sms_code/
    #  1.创建一个类视图
    # 2.从前端获取参数
    # 3.校验参数
    # 4.发送短信验证码
    # 5.保存短信验证码
    # 6.返回前端
    """
    def post(self, request):
        """
        # 2.从前端获取参数
        json_data = request.bdy
        dict_data = json.loads(json_data)

        # 3.校验参数
        mobile = dict_data.get('mobile')
        text = dict_data.get('text')
        image_code_id = dict_data.get('image_code_id')

        # 如果使用以上方式，手机号要验证是否为空，是否满足格式，是否已注册（既mobile判断三次）
        # 图形验证码是否为空，是否与数据库中保存一致，（既text判断两次）
        # uuid格式是否正确（既uuid判断一次）
        # 那接下来的验证将会有很多的if...else....
        # 所以以上的方法我们不采用，而是换用form表单来实现验证
        """
        form = CheckImgCodeForm(request.POST)
        if form.is_valid():
            return to_json_data(errmsg='发送短信成功！')
        else:
            # 将表单的报错信息进行拼接
            err_msg_list = []
            for item in form.errors.values():
                err_msg_list.append(item[0])
            err_msg_str = '/'.join(err_msg_list)
            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)



